﻿#ifndef DESERIALIZEMACRO_HPP
#define DESERIALIZEMACRO_HPP
/************************************************
  * 描述: 封装、实现JSON数据的反序列化
  * File: deserializemacro.h
  * Author: qijiangyong@mozihealthcare.cn
  * Date: 2025-07-11
  * Update:
  ***********************************************/
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <variant>
#include <utility>
#include <optional>
#include <simdjson.h>
#include <type_traits>

  // ================== Qt 类型支持 ==================

#include <QString>
#include <QDateTime>
#include <QByteArray>
#include <common/xlist.hpp>

using namespace simdjson;

// ================== 基础反序列化工具 ==================
namespace detail {
    // 基础类型反序列化
    // 布尔类型 (非模板版本)
    inline bool deserialize_field(ondemand::value value, bool& target) {
        return !value.get(target);
    }

    // 整数类型 - 添加非模板版本
    inline bool deserialize_field(ondemand::value value, int& target) {
    	if (value.type() == ondemand::json_type::string)
    	{
    		std::string_view stemp;
    		if (!value.get(stemp))
    		{
    			if (!stemp.empty())
    			{
    				target = std::stoi(stemp.data());
    				return true;
    			}
    		}
    	}
    	//.
        int64_t temp;
        if (value.get(temp)) return false;
        if (temp < std::numeric_limits<int>::min() || temp > std::numeric_limits<int>::max()) {
            return false;
        }
        target = static_cast<int>(temp);
        return true;
    }

    inline bool deserialize_field(ondemand::value value, int64_t& target) {
    	if (value.type() == ondemand::json_type::string)
    	{
    		std::string_view stemp;
    		if (!value.get(stemp))
    		{
    			if (!stemp.empty())
    			{
    				target = std::stoll(stemp.data());
    				return true;
    			}
    		}
    	}
    	//.
        return !value.get(target);
    }

    inline bool deserialize_field(ondemand::value value, uint64_t& target) {
    	if (value.type() == ondemand::json_type::string)
    	{
    		std::string_view stemp;
    		if (!value.get(stemp))
    		{
    			if (!stemp.empty())
    			{
    				target = std::stoull(stemp.data());
    				return true;
    			}
    		}
    	}
    	//.
        return !value.get(target);
    }

	inline bool deserialize_field(ondemand::value value, uint32_t& target)
    {
    	if (value.type() == ondemand::json_type::string)
    	{
    		std::string_view stemp;
    		if (!value.get(stemp))
    		{
    			if (!stemp.empty())
    			{
    				target = std::stoul(stemp.data());
    				return true;
    			}
    		}
    	}
    	//.
    	uint64_t temp64;
    	if (!value.get(temp64))
    	{
    		target = static_cast<uint32_t>(temp64);
    		return true;
    	}
    	return false;
    }

    // 浮点类型 (非模板版本)
    inline bool deserialize_field(ondemand::value value, double& target) {
    	if (value.type() == ondemand::json_type::string)
    	{
    		std::string_view stemp;
    		if (!value.get(stemp))
    		{
    			if (!stemp.empty())
    			{
    				target = std::stod(stemp.data());
    				return true;
    			}
    		}
    	}
    	//.
        return !value.get(target);
    }

	inline bool deserialize_field(ondemand::value value, float& target)
    {
	    double dtemp;
    	if (deserialize_field(value, dtemp))
    	{
    		target = static_cast<float>(dtemp);
    		return true;
    	}
    	return false;
    }

    // 字符串类型 (非模板版本)
    inline bool deserialize_field(ondemand::value value, std::string& target) {
    	if (value.type() == ondemand::json_type::string) {
    		std::string_view view = value.get_string();
    		target = view.data();
    	}
    	else if (value.is_null()) {
    		target.clear();
    		std::cout << "value is null" << std::endl;
    	}
    	else {
    		std::cerr << "type is not a string or null!" << std::endl;
    		if (value.type() == ondemand::json_type::number)
    		{
    			int64_t ll_val;
    			uint64_t ull_val;
    			if (value.get(ll_val) == SUCCESS)
    			{
    				target = std::to_string(ll_val);
    			}
    			else if (value.get(ull_val) == SUCCESS)
    			{
    				target = std::to_string(ull_val);
    			}
    			else {
    				double double_val;
    				if (value.get(double_val)) return false;
    				target = std::to_string(double_val);
    			}
    			return true;
    		}
    		return false;
    	}
    	return true;
    }

    // 通用整数类型 (模板版本)
    template <typename T>
    inline auto deserialize_field(ondemand::value value, T& target)
        -> std::enable_if_t<std::is_integral_v<T> &&
                            !std::is_same_v<T, bool> &&
                            !std::is_same_v<T, int> &&
                            !std::is_same_v<T, int64_t> &&
                            !std::is_same_v<T, uint64_t>, bool>
    {
        if constexpr (std::is_signed_v<T>) {
            int64_t temp;
            if (value.get(temp)) return false;
            if (temp < std::numeric_limits<T>::min() || temp > std::numeric_limits<T>::max()) {
                return false;
            }
            target = static_cast<T>(temp);
        } else {
            uint64_t temp;
            if (value.get(temp)) return false;
            if (temp > static_cast<uint64_t>(std::numeric_limits<T>::max())) {
                return false;
            }
            target = static_cast<T>(temp);
        }
        return true;
    }

    // 通用浮点类型 (模板版本)
    template <typename T>
    inline auto deserialize_field(ondemand::value value, T& target)
        -> std::enable_if_t<std::is_floating_point_v<T> &&
                            !std::is_same_v<T, double>, bool>
    {
        double temp;
        if (value.get(temp)) return false;
        target = static_cast<T>(temp);
        return true;
    }

    // 向量容器
    template <typename T>
    inline bool deserialize_field(ondemand::value value, std::vector<T>& target) {
        auto array = value.get_array();
        if (array.error()) return false;

        target.clear();
        for (auto element : array) {
            T item;
            if (!deserialize_field(element.value(), item)) {
                // return false;
            	continue;
            }
            target.push_back(std::move(item));
        }
        return true;
    }

    // 字典类型 - 修复键类型转换问题
    template <typename V>
    inline bool deserialize_field(ondemand::value value, std::map<std::string, V>& target) {
        auto obj = value.get_object();
        if (obj.error()) return false;

        for (auto field : obj) {
            // 正确获取键为 string_view
            std::string_view key_view;
            if (field.unescaped_key().get(key_view)) {
                return false;
            }

            // 转换为 std::string
            std::string key(key_view);

            // 反序列化值
            V val;
            if (!deserialize_field(field.value(), val)) {
                // return false;
            	continue;
            }

            // 插入到 map
            target.emplace(std::move(key), std::move(val));
        }
        return true;
    }

    // 检测deserialize函数是否存在
    template <typename T>
    auto test_deserialize(int) -> decltype(
            deserialize(std::declval<ondemand::value>(), std::declval<T&>()),
            std::true_type{}
    );

    template <typename>
    std::false_type test_deserialize(...);

    template <typename T>
    struct has_deserialize : decltype(test_deserialize<T>(0)) {};

    // 嵌套结构体支持 - 添加类类型约束
    template <typename T>
    inline auto deserialize_field(ondemand::value value, T& target)
    -> std::enable_if_t<has_deserialize<T>::value && std::is_class_v<T>, bool>
    {
        return deserialize(value, target);
    }

    ///////////////////////////////////////////////////////////////////////////
    // Qt 类型支持
    // QString 支持
    inline bool deserialize_field(ondemand::value value, QString& target) {
    	if (value.type() == ondemand::json_type::string) {
    		std::string_view view = value.get_string();
    		target = QString::fromUtf8(view.data(), static_cast<int>(view.size()));
    	}
    	else if (value.is_null()) {
    		target.clear();
    		std::cout << "value is null" << std::endl;
    	}
    	else {
    		if (value.type() == ondemand::json_type::number)
    		{
    			qlonglong ll_val;
    			qulonglong ull_val;
    			if (value.get(ll_val) == SUCCESS)
    			{
    				target = QString::number(ll_val);
    			}
    			else if (value.get(ull_val) == SUCCESS)
    			{
    				target = QString::number(ull_val);
    			}
    			else {
    				double double_val;
    				if (value.get(double_val)) return false;
    				target = QString::number(double_val);
    			}
				return true;
    		}
    		std::cerr << "type is null or failed!" << std::endl;
    		return false;
    	}
    	return true;
    }

	// QVariant 支持
	inline bool deserialize_field(ondemand::value value, QVariant& target)
    {
    	// simple version
    	// std::string_view view;
    	// if (value.get(view)) return false;
    	// auto strVal = QString::fromUtf8(view.data(), static_cast<int>(view.size()));
    	// qDebug() << "var str:" << strVal;
    	// target = QVariant::fromValue(strVal);

    	// complete version
    	ondemand::json_type type;
    	if (value.type().get(type)) {
    		return false;
    	}

    	switch (type) {
    	case ondemand::json_type::string: {
    		std::string_view view;
    		if (value.get(view)) return false;
    		target = QVariant(QString::fromUtf8(view.data(), static_cast<int>(view.size())));
    		break;
    	}
    	case ondemand::json_type::number: {
    		// 尝试整数，如果整数解析失败再尝试浮点数
    		qlonglong ll_val;
    		qulonglong ull_val;
			if (value.get(ll_val) == SUCCESS)
    		{
    			target = QVariant::fromValue(ll_val);
    		}
    		else if (value.get(ull_val) == SUCCESS)
    		{
    			target = QVariant::fromValue(ull_val);
    		}
    		else {
    			double double_val;
    			if (value.get(double_val)) return false;
    			target = QVariant::fromValue(double_val);
    		}
    		break;
    	}
    	case ondemand::json_type::boolean: {
    		bool bool_val;
    		if (value.get(bool_val)) return false;
    		target = QVariant::fromValue(bool_val);
    		break;
    	}
    	case ondemand::json_type::null: {
    		target = QVariant();
    		break;
    	}
    		// 对于数组和对象，我们可能需要更复杂的处理，这里先不实现
    	case ondemand::json_type::array:
		case ondemand::json_type::object:
		default:
			// 对于不支持的类型，我们可以将其转换为字符串形式，或者跳过
			// 这里我们将其转换为字符串形式（使用raw_json_token）
			std::string_view view = value.raw_json_token();
    		if (view.empty())
    		{
    			if (value.get(view))
    				return false;
    		}
    		target = QVariant(QString::fromUtf8(view.data(), static_cast<int>(view.size())));
    		break;
    	}
    	return target.isValid();
    }

    // QDateTime 支持 (ISO 8601 格式)
    inline bool deserialize_field(ondemand::value value, QDateTime& target) {
        std::string_view view;
        if (value.get(view)) return false;
        target = QDateTime::fromString(QString::fromUtf8(view.data(), static_cast<int>(view.size())), Qt::ISODate);
        return target.isValid();
    }

    // QDate 支持 (ISO 8601 格式)
    inline bool deserialize_field(ondemand::value value, QDate& target) {
        std::string_view view;
        if (value.get(view)) return false;
        target = QDate::fromString(QString::fromUtf8(view.data(), static_cast<int>(view.size())), Qt::ISODate);
        return target.isValid();
    }

    // QTime 支持 (ISO 8601 格式)
    inline bool deserialize_field(ondemand::value value, QTime& target) {
        std::string_view view;
        if (value.get(view)) return false;
        target = QTime::fromString(QString::fromUtf8(view.data(), static_cast<int>(view.size())), Qt::ISODate);
        return target.isValid();
    }

    // QByteArray 支持 (Base64 编码)
    inline bool deserialize_field(ondemand::value value, QByteArray& target) {
    	if (value.type() == ondemand::json_type::number)
    	{
    		qlonglong ll_val;
    		qulonglong ull_val;
    		if (value.get(ll_val) == SUCCESS)
    		{
    			target = QByteArray::number(ll_val);
    		}
    		else if (value.get(ull_val) == SUCCESS)
    		{
    			target = QByteArray::number(ull_val);
    		}
    		else {
    			double double_val;
    			if (value.get(double_val)) return false;
    			target = QByteArray::number(double_val);
    		}
    		return true;
    	}
        std::string_view view;
        if (value.get(view)) return false;
        target = QByteArray::fromBase64(QByteArray(view.data(), static_cast<int>(view.size())));
        return true;
    }

    // QList<T> 支持
    template <typename T>
    inline bool deserialize_field(ondemand::value value, QList<T>& target) {
        auto array = value.get_array();
        if (array.error()) return false;

        target.clear();
        for (auto element : array) {
            T item;
            if (!deserialize_field(element.value(), item)) {
                // return false;
            	continue;
            }
            target.append(std::move(item));
        }
        return true;
    }

	// XList<T> 支持
	template <typename T>
	inline bool deserialize_field(ondemand::value value, xlist::XList<T>& target) {
    	auto array = value.get_array();
    	if (array.error()) return false;

    	// target.clear();
    	for (auto element : array) {
    		T item;
    		if (!deserialize_field(element.value(), item)) {
    			// return false;
    			continue;
    		}
    		target.Add(std::move(item));
    	}
    	return true;
    }

    // QVector<T> 支持
    template <typename T>
    inline bool deserialize_field(ondemand::value value, QVector<T>& target) {
        auto array = value.get_array();
        if (array.error()) return false;

        target.clear();
        for (auto element : array) {
            T item;
            if (!deserialize_field(element.value(), item)) {
                // return false;
            	continue;
            }
            target.append(std::move(item));
        }
        return true;
    }

    // QMap<QString, V> 支持
    template <typename V>
    inline bool deserialize_field(ondemand::value value, QMap<QString, V>& target) {
        auto obj = value.get_object();
        if (obj.error()) return false;

        for (auto field : obj) {
            std::string_view key_view;
            if (field.unescaped_key().get(key_view)) {
                return false;
            }
            QString key = QString::fromUtf8(key_view.data(), static_cast<int>(key_view.size()));

            V val;
            if (!deserialize_field(field.value(), val)) {
                // return false;
            	continue;
            }

            target.insert(key, std::move(val));
        }
        return true;
    }

	// std::optional 支持
	template <typename T>
	inline bool deserialize_field(ondemand::value value, std::optional<T>& target) {
    	T temp;
    	if (deserialize_field(value, temp)) {
    		target = std::move(temp);
    		// return true;
    	}
    	else
    		target.reset();
    	return true;
    }
}

/////////////////////////////////////////////////////////////
// 非侵入式反序列化框架【系列宏】
// 简化大型结构体的注册
#define BEGIN_DESERIALIZE_ADAPTER(StructName) \
    inline bool deserialize(ondemand::value value, StructName& target) { \
        auto obj = value.get_object(); \
        if (obj.error()) { \
            std::cerr << "Expected object for " #StructName << std::endl; \
            return false; \
        } \
        bool all_ok = true;

#define DESERIALIZE_FIELD(field_name) \
{ \
    auto result = obj[#field_name]; \
    if (result.error() == NO_SUCH_FIELD) { \
        std::cerr << "Missing required field: " #field_name << std::endl; \
        all_ok = true; \
    } else if (result.error()) { \
        std::cerr << "Error accessing field: " #field_name << std::endl; \
        all_ok = false; \
    } else { \
        if (!::detail::deserialize_field(result.value(), target.field_name)) { \
            std::cerr << "Deserialization failed for field: " #field_name << std::endl; \
            all_ok = false; \
        } \
    } \
}

#define DESERIALIZE_OPTIONAL_FIELD(field_name) \
{ \
    auto result = obj[#field_name]; \
    if (result.error() == NO_SUCH_FIELD) { \
        ; \
    } else if (result.error()) { \
        std::cerr << "Error accessing optional field: " #field_name << std::endl; \
        all_ok = false; \
    } else { \
        if (!::detail::deserialize_field(result.value(), target.field_name)) { \
            std::cerr << "Deserialization failed for optional field: " #field_name << std::endl; \
            all_ok = false; \
        } \
    } \
}

#define END_DESERIALIZE_ADAPTER() \
    return all_ok; \
}

// =============== 顶层反序列化函数 ===============
// 处理 ondemand::value -> 目标类型
template <typename T>
bool deserialize(ondemand::value value, T& target) {
    return detail::deserialize_field(value, target);
}

// 处理 ondemand::document -> 目标类型
template <typename T>
bool deserialize(ondemand::document& doc, T& target) {
    ondemand::value val;
    auto error = doc.get_value().get(val);
    if (error) {
        std::cerr << "Failed to get document value: " << error << std::endl;
        return false;
    }
    return deserialize(val, target);
}

// 针对 vector 的特化版本
template <typename T>
bool deserialize(ondemand::value value, std::vector<T>& target) {
    auto arr = value.get_array();
    if (arr.error()) {
        std::cerr << "Expected array for vector: " << arr.error() << std::endl;
        return false;
    }

    target.clear();
    bool all_ok = true;

    // 尝试预分配内存
    size_t count = 0;
    if (arr.count_elements().get(count) == SUCCESS) {
        target.reserve(count);
    }

    size_t index = 0;
    for (auto element : arr) {
        T item;
        if (!deserialize(element.value(), item)) {
            std::cerr << "Failed to deserialize vector element at index: " << index << std::endl;
            all_ok = false;
        } else {
            target.push_back(std::move(item));
        }
        index++;
    }
    return all_ok;
}

// 针对 QList 的特化版本
template <typename T>
bool deserialize(ondemand::value value, QList<T>& target) {
    auto arr = value.get_array();
    if (arr.error()) {
        std::cerr << "Expected array for vector: " << arr.error() << std::endl;
        return false;
    }

    target.clear();
    bool all_ok = true;

    // 尝试预分配内存
    size_t count = 0;
    if (arr.count_elements().get(count) == SUCCESS) {
        target.reserve(static_cast<int>(count));
    }

    size_t index = 0;
    for (auto element : arr) {
        T item;
        if (!deserialize(element.value(), item)) {
            std::cerr << "Failed to deserialize vector element at index: " << index << std::endl;
            all_ok = false;
        }
        else {
            target.push_back(std::move(item));
        }
        index++;
    }
    return all_ok;
}

// 针对 XList 的特化版本
template <typename T>
bool deserialize(ondemand::value value, xlist::XList<T>& target)
{
	QList<T> temp;
	bool result = deserialize(value, temp);
	target = xlist::XList<T>(temp);
	return result;
}

#endif // DESERIALIZEMACRO_HPP
